<html>
<head><meta charset="utf-8"><title>what-part-of-nll-allows-this · t-compiler/wg-nll · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/index.html">t-compiler/wg-nll</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/what-part-of-nll-allows-this.html">what-part-of-nll-allows-this</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="129512245"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/what-part-of-nll-allows-this/near/129512245" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/what-part-of-nll-allows-this.html#129512245">(Jul 12 2018 at 02:45)</a>:</h4>
<p>From <a href="https://stackoverflow.com/q/51295816/155423" target="_blank" title="https://stackoverflow.com/q/51295816/155423">a SO question</a>:</p>
<div class="codehilite"><pre><span></span><span class="k">struct</span> <span class="nc">Superhero</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">name</span>: <span class="kp">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="nb">String</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">power</span>: <span class="kp">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;Bruce Wayne&quot;</span><span class="p">.</span><span class="n">to_string</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">r</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">98</span><span class="p">;</span><span class="w"></span>
<span class="w">        </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="kd">let</span><span class="w"> </span><span class="n">hero</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Superhero</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                </span><span class="n">name</span>: <span class="kp">&amp;</span><span class="nc">n</span><span class="p">,</span><span class="w"></span>
<span class="w">                </span><span class="n">power</span>: <span class="kp">&amp;</span><span class="nc">p</span><span class="p">,</span><span class="w"></span>
<span class="w">            </span><span class="p">};</span><span class="w"></span>
<span class="w">            </span><span class="n">r</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hero</span><span class="p">.</span><span class="n">name</span><span class="p">;</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="n">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">r</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>This fails before NLL and compiles with NLL, but I don't understand which part of NLL enables it. Pre NLL, my argument would have been:</p>
<blockquote>
<p>Since <code>Superhero</code> has a single lifetime for both fields, when you create it, <code>'a</code> is unified to be the intersection of the variables, which is the inner scope. When you try to get <code>hero.name</code> back out, the fact that it came from a longer lifetime originally is lost, so you get the error.</p>
<p>You can fix this by assigning two distinct lifetimes for each field</p>
</blockquote>



<a name="129512314"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/what-part-of-nll-allows-this/near/129512314" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/what-part-of-nll-allows-this.html#129512314">(Jul 12 2018 at 02:47)</a>:</h4>
<p>But AIUI, that same argument would be true in NLL world. Is <code>hero</code> in some weird superposition of lifetimes? Is the MIR borrowchecker clever enough to see that <code>power</code> is never used so it never plays a part in lifetimes?</p>



<a name="129517042"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/what-part-of-nll-allows-this/near/129517042" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/what-part-of-nll-allows-this.html#129517042">(Jul 12 2018 at 05:11)</a>:</h4>
<p>You are correct that <code>r</code> cannot outlive <code>p</code> <em>or</em> <code>n</code>. The thing that makes this work under NLL is that we consider <code>r</code> to be "live" only until its last use, and not until the end of the block it is declared in. In this case, that last use is within the scope of <code>p</code>, so everything works. But this variant, where I moved the <code>println!</code> outside of the block declaring <code>p</code>, fails to compile:</p>
<div class="codehilite"><pre><span></span><span class="cp">#![feature(nll)]</span><span class="w"></span>

<span class="k">struct</span> <span class="nc">Superhero</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">name</span>: <span class="kp">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="nb">String</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">power</span>: <span class="kp">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;Bruce Wayne&quot;</span><span class="p">.</span><span class="n">to_string</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">r</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">98</span><span class="p">;</span><span class="w"></span>
<span class="w">        </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="kd">let</span><span class="w"> </span><span class="n">hero</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Superhero</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                </span><span class="n">name</span>: <span class="kp">&amp;</span><span class="nc">n</span><span class="p">,</span><span class="w"></span>
<span class="w">                </span><span class="n">power</span>: <span class="kp">&amp;</span><span class="nc">p</span><span class="p">,</span><span class="w"></span>
<span class="w">            </span><span class="p">};</span><span class="w"></span>
<span class="w">            </span><span class="n">r</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hero</span><span class="p">.</span><span class="n">name</span><span class="p">;</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="n">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{}&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">r</span><span class="p">);</span><span class="w"> </span><span class="c1">// &lt;-- I moved this to outside of the scope of `p`</span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="129517043"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/what-part-of-nll-allows-this/near/129517043" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/what-part-of-nll-allows-this.html#129517043">(Jul 12 2018 at 05:11)</a>:</h4>
<p>I get:</p>
<div class="codehilite"><pre><span></span>error[E0597]: `p` does not live long enough
  --&gt; src/main.rs:16:24
   |
16 |                 power: &amp;p,
   |                        ^^ borrowed value does not live long enough
...
20 |     }
   |     - borrowed value only lives until here
21 |     println!(&quot;{}&quot;, r);
   |                    - borrow later used here
</pre></div>



<a name="129517087"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/what-part-of-nll-allows-this/near/129517087" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/what-part-of-nll-allows-this.html#129517087">(Jul 12 2018 at 05:12)</a>:</h4>
<p>It <em>would</em> be nice -- and isn't out of the question at some point -- if we could highlight the connection to <code>Superhero</code>'s single lifetime parameter</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>